package com.neusoft.databus.core.service;

import java.io.Serializable;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import com.neusoft.bizcore.common.utils.DateUtil;
import com.neusoft.databus.core.flume.MetricCollectionProcessor;
import com.neusoft.databus.core.job.CollectMetricJob;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class StatisticService {

    @Autowired
    private MetricCollectionProcessor metricCollectionProcessor;

    private final Map<String, Metric> dailyReportMap = new ConcurrentHashMap<>();

    // 0/5 * * * * ?   //0 0/3 * * * ?
    @Scheduled(cron = "0/5 * * * * ?")
    public void run() {
        this.getCommandProcessorStatis();
        this.print();
    }

    public void getCommandProcessorStatis() {
        final long successCount = this.metricCollectionProcessor.getSuccessTotal().getAndSet(0);
        final long failCount = this.metricCollectionProcessor.getFailTotal().getAndSet(0);
        final long sendCount = CollectMetricJob.sendTotal.getAndSet(0);

        final String date = DateUtil.date2String(new Date(), DateUtil.PATTERN_DATE);
        if (this.dailyReportMap.containsKey(date)) {
            final Metric metric = this.dailyReportMap.get(date);
            metric.setSuccessCount(metric.getSuccessCount() + successCount);
            metric.setFailCount(metric.getFailCount() + failCount);
            metric.setSendCount(metric.getSendCount() + sendCount);
        } else {
            final Metric metric = new Metric(sendCount, successCount, failCount);
            this.dailyReportMap.put(date, metric);
        }
    }

    public void print() {
        this.dailyReportMap.entrySet().stream().forEach(entry -> {

            final String text = entry.getValue().getSendCount() + "-" + entry.getValue().getSuccessCount() + "-"
                    + entry.getValue().getFailCount();

            final int charLength = text.length();
            final StringBuilder builder = new StringBuilder();
            for (int i = 0; i < (20 - charLength); i++) {
                builder.append(" ");
            }
            StatisticService.log.info("-------------------------------------");
            StatisticService.log.info("| {} | {}" + builder.toString() + " |", entry.getKey(), text);
            StatisticService.log.info("-------------------------------------");
        });
    }

    @Getter
    @Setter
    @NoArgsConstructor
    @AllArgsConstructor
    static class Metric implements Serializable {
        private static final long serialVersionUID = 1L;

        private long sendCount;
        private long successCount;
        private long failCount;
    }
}
